From: Jan Beulich Date: Wed, 11 May 2016 07:47:21 +0000 (+0200) Subject: x86: correct remaining extended CPUID level checks X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~1130 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=a6abcd8f758d968f6eb4d93ab37db4388eb9df7e;p=xen.git x86: correct remaining extended CPUID level checks We should consistently check the upper 16 bits to be equal 0x8000 and only then the full value to be >= the desired level. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Release-acked-by: Wei Liu --- diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index f3501fdf47..0999997fd2 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -133,7 +133,10 @@ __start: /* Interrogate CPU extended features via CPUID. */ mov $0x80000000,%eax cpuid + shld $16,%eax,%ecx xor %edx,%edx + cmp $0x8000,%cx # any function @ 0x8000xxxx? + jne 1f cmp $0x80000000,%eax # any function > 0x80000000? jbe 1f mov $0x80000001,%eax diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 4b560619ae..760543bc1d 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -297,9 +297,12 @@ static void generic_identify(struct cpuinfo_x86 *c) /* AMD-defined flags: level 0x80000001 */ c->extended_cpuid_level = cpuid_eax(0x80000000); - cpuid(0x80000001, &tmp, &tmp, - &c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)], - &c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]); + if ((c->extended_cpuid_level >> 16) != 0x8000) + c->extended_cpuid_level = 0; + if (c->extended_cpuid_level > 0x80000000) + cpuid(0x80000001, &tmp, &tmp, + &c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)], + &c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]); if (c == &boot_cpu_data) bootsym(cpuid_ext_features) = c->x86_capability[cpufeat_word(X86_FEATURE_NX)]; diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index 6dbb14def5..1fa9e47426 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -605,7 +605,9 @@ static void __init efi_arch_handle_module(struct file *file, const CHAR16 *name, static void __init efi_arch_cpu(void) { - if ( cpuid_eax(0x80000000) > 0x80000000 ) + uint32_t eax = cpuid_eax(0x80000000); + + if ( (eax >> 16) == 0x8000 && eax > 0x80000000 ) { cpuid_ext_features = cpuid_edx(0x80000001); boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)] diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 917db564bb..7492030a13 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -884,7 +884,7 @@ const char *hvm_efer_valid(const struct vcpu *v, uint64_t value, ASSERT(v->domain == current->domain); hvm_cpuid(0x80000000, &level, NULL, NULL, NULL); - if ( level >= 0x80000001 ) + if ( (level >> 16) == 0x8000 && level > 0x80000000 ) { unsigned int dummy; diff --git a/xen/arch/x86/hvm/mtrr.c b/xen/arch/x86/hvm/mtrr.c index 7ab7f6325c..f7831ff8e1 100644 --- a/xen/arch/x86/hvm/mtrr.c +++ b/xen/arch/x86/hvm/mtrr.c @@ -455,7 +455,7 @@ bool_t mtrr_var_range_msr_set( { phys_addr = 36; hvm_cpuid(0x80000000, &eax, NULL, NULL, NULL); - if ( eax >= 0x80000008 ) + if ( (eax >> 16) == 0x8000 && eax >= 0x80000008 ) { hvm_cpuid(0x80000008, &eax, NULL, NULL, NULL); phys_addr = (uint8_t)eax;